package com.seaside.park.controller.cabinet;

import com.alibaba.fastjson.JSON;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.IpKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import com.seaside.common.bean.Result;
import com.seaside.park.bean.cabinet.Cabinet;
import com.seaside.park.bean.cabinet.CabinetCell;
import com.seaside.park.bean.cabinet.GoodInfo;
import com.seaside.park.bean.cabinet.vo.CellVO;
import com.seaside.park.bean.cabinet.vo.GoodVO;
import com.seaside.park.bean.wxpay.WxPayBean;
import com.seaside.park.service.CabinetService;
import com.seaside.park.service.GoodService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/shareCabinet")
@Slf4j
public class CabinetController  extends AbstractWxPayApiController{

    @Autowired
    private CabinetService cabinetService;

    @Autowired
    private GoodService goodService;

    @Autowired
    WxPayBean wxPayBean;

    private String notifyUrl;
    private String refundNotifyUrl;
    private static final String USER_PAYING = "USERPAYING";


    @Override
    public WxPayApiConfig getApiConfig() {
        WxPayApiConfig apiConfig;

        try {
            apiConfig = WxPayApiConfigKit.getApiConfig(wxPayBean.getAppId());
        } catch (Exception e) {
            apiConfig = WxPayApiConfig.builder()
                    .appId(wxPayBean.getAppId())
                    .mchId(wxPayBean.getMchId())
                    .partnerKey(wxPayBean.getPartnerKey())
                    .certPath(wxPayBean.getCertPath())
                    .domain(wxPayBean.getDomain())
                    .build();
        }
        notifyUrl = apiConfig.getDomain().concat("/wxPay/payNotify");
        refundNotifyUrl = apiConfig.getDomain().concat("/wxPay/refundNotify");
        return apiConfig;
    }

    @RequestMapping("/depositCell")
    @ResponseBody
    public Result<String> depositCell(HttpServletRequest request) {
        Result result;
        try{
            String userOpenid = request.getParameter("userOpenid");
            int cabinetId = Integer.valueOf(request.getParameter("cabinetId"));
            String cellNo = request.getParameter("cellNo");
            int time = Integer.valueOf(request.getParameter("time"));
            String duration = request.getParameter("duration");
            String goodName = request.getParameter("goodName");
            int goodType = Integer.valueOf(request.getParameter("goodType"));
            String getPhone = request.getParameter("getPhone");
            if(userOpenid.equals(null) || cellNo.equals(null) || duration.equals(null) || goodName.equals(null)){
                result = Result.Error("信息填写错误!");
            }
            int goodId = cabinetService.depositCell(userOpenid,cabinetId,cellNo,goodType,goodName,duration,time,getPhone);
            if(goodId>0){
                result = Result.OK("恭喜,存放成功!",goodId);
            }else{
                result =  Result.Error("抱歉，存放出现错误!");
            }
        }catch (Exception e) {
            e.printStackTrace();
            result = Result.Error("抱歉,存放错误!请检查填写信息");
        }
        return result;
    }

    /**
     * 根据商品分类获得列表
     * @param typeId 分类Id
     * @return
     */
    @RequestMapping("/getGoodListByTypeId")
    @ResponseBody
    public Result<GoodInfo> getGoodInfoById(int typeId) {
        Result result;
        try {
            List<GoodInfo> data = goodService.getGoodListByType(typeId);
            if(data!=null)
            {
                result = Result.OK("查看物品详情",data);
            }else{
                result = Result.Error("抱歉！没有查询到商品信息!");
            }
        }catch (Exception e) {
            e.printStackTrace();
            log.error("查询商品信息失败!" + e.getMessage());
            result = Result.Error("查询商品信息失败!" + e.getMessage());
        }
        return result;
    }

    @RequestMapping("/getGoodInfoById")
    @ResponseBody
    public Result<GoodInfo> getGoodInfoById(HttpServletRequest request) {
        Result result;
        try {
            int goodInfoId = Integer.parseInt(request.getParameter("goodInfoId"));
            GoodInfo data =cabinetService.getGoodInfoById(goodInfoId);
            List<String> images = new ArrayList<>();
            if(data!=null)
            {
                String[] temp = data.getGoodImages().split(";");
                for(String image : temp) {
                    if(image!="") {
                        images.add(image);
                    }
                }
                data.setGoodImageList(images);
                result = Result.OK("查看物品详情",data);
            }else{
                result = Result.Error("抱歉！没有查询到商品信息!");
            }
        }catch (Exception e) {
            log.error("查询商品信息失败!" + e.getMessage());
            result = Result.Error("抱歉！没有查询到商品信息!" + e.getMessage());
        }
        return result;
    }

    @RequestMapping("/getUsedCells")
    @ResponseBody
    public Result<List<CabinetCell>> getUsedCells(HttpServletRequest request) {
        Result result;
        try {
            int cabinetId = Integer.parseInt(request.getParameter("cabinetId"));
            List<CabinetCell> dataList=cabinetService.getUsedCellsByCabinetId(cabinetId);
            if(dataList!=null)
            {
                result = Result.OK("已经为您查询到存放记录，请选择柜子打开!",dataList);
            }else{
                result = Result.Error("没有查询到任何存放记录，请确认柜子!");
            }
        }catch (Exception e) {
            log.error(e.getMessage());
            result = Result.Error("柜子数据读取错误!请重试!" + e.getMessage());
        }
        return result;
    }

    @RequestMapping("/getMyCells")
    @ResponseBody
    public Result<List<CellVO>> getMyCells(HttpServletRequest request) {
        Result result;
        try {
            String userOpenId = request.getParameter("userOpenId");
            int cabinetId = Integer.valueOf(request.getParameter("cabinetId"));
            List<CellVO> dataList=cabinetService.getCellsByUserOpenId(cabinetId,userOpenId);
            if(dataList!=null)
            {
                result = Result.OK("已经为您查询到存放记录，请选择柜子打开!",dataList);
            }else{
                result = Result.Error("没有查询到您的存放记录，请确认柜子!");
            }
        }catch (Exception e) {
            log.error(e.getMessage());
            result = Result.Error("柜子数据读取错误!请重试!" + e.getMessage());
        }
        return result;
    }

    @RequestMapping("/openCabinetCellByOpenPwd")
    @ResponseBody
    @Transactional
    public Result openCabinetCellByOpenPwd(HttpServletRequest request) {
        Result result;
        String cellNo = request.getParameter("cellNo");
        int cabinetId = Integer.parseInt(request.getParameter("cabinetId"));
        String openPwd = request.getParameter("openPwd");
        if(cabinetId==0 || cellNo.equals(null) || cellNo.equals("") || openPwd.equals("") || openPwd==null){
            return Result.Error("开柜失败!请选择箱子或输入正确密码!");
        }

        if(cellNo.contains("-")){
            cellNo = cellNo.split("-")[0];
        }

        if(cabinetService.openCabinetCellByOpenPwd(cabinetId,cellNo,openPwd)){
            //改变格子的状态
            if (cabinetService.changeCellStatus(cabinetId,cellNo)){
                result = Result.OK("开柜成功！");
            }else{
                result = Result.OK("开柜失败！");
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        }else{
            result = Result.Error("开柜失败!请选择正确的柜子!");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return result;
    }

    @RequestMapping("/openCabinetCell")
    @ResponseBody
    @Transactional
    public Result openCabinetCell(HttpServletRequest request) {
        Result result;
        String cellNo = request.getParameter("cellNo");
        int cabinetId = Integer.parseInt(request.getParameter("cabinetId"));
        String openPwd = "";
        if(cabinetId==0 || cellNo.equals(null) || cellNo.equals("")){
            return Result.Error("开柜失败!");
        }
        try {
            openPwd = request.getParameter("openPwd");
        }catch (Exception e){}

        if(cellNo.contains("-")){
            cellNo = cellNo.split("-")[0];
        }

        if(cabinetService.openCabinetCell(cabinetId,cellNo)){
            //改变格子的状态
            if (cabinetService.changeCellStatus(cabinetId,cellNo)){
                result = Result.OK("开柜成功！");
            }else{
                result = Result.OK("开柜失败！");
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        }else{
            result = Result.Error("开柜失败!请选择正确的柜子!");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return result;
    }

    @RequestMapping("/publishMarket")
    @ResponseBody
    public Result publishMarket(HttpServletRequest request) {
        Result result;
        try{
            int goodId = Integer.valueOf(request.getParameter("goodId"));
            float goodPrice = Float.valueOf(request.getParameter("goodPrice"));
            String goodDegree = request.getParameter("goodDegree");
            String goodDesc = request.getParameter("goodDesc");
            String goodImages = request.getParameter("goodImages");

            if(goodId==0 ||  goodDegree.equals(null) || goodDesc.equals(null)){
                result = Result.Error("信息填写错误!");
            }
            if(cabinetService.publishGood(goodId,goodPrice,goodDegree,goodDesc,goodImages)){
                result = Result.OK("恭喜,商品发布成功!");
            }else{
                result =  Result.Error("抱歉，商品发布错误!。");
            }
        }catch (Exception e) {
            log.error("物品发布到商城失败!" + e.getMessage());
            result = Result.Error("请检查填写信息");
        }
        return result;
    }

    @RequestMapping("/getValidCells")
    @ResponseBody
    public Result<CabinetCell> startDepositCell(@RequestParam int cabinetId) {
        //int cabinetId = Integer.valueOf(cabinetId);
        //查询该柜子空闲的格子
        return Result.OK("查询剩余格子成功！",cabinetService.getValidCells(cabinetId));
    }

    @RequestMapping("/getCabinetById")
    @ResponseBody
    public Result<Cabinet> getCabinetById(int cabinetId) {
        Cabinet ret = cabinetService.getCabinetById(cabinetId);
        if(!ret.equals(null))
        {
            //查询可用格子
            ret.setValidCells(cabinetService.getValidCells(cabinetId).size());
            return Result.OK("查询柜子清单成功!",ret);
        }else{
            return Result.Error("查询柜子信息失败!");
        }
    }

    @RequestMapping("/getGoodByCabinetId")
    @ResponseBody
    public Result<List<GoodVO>> getGoodByCabinetId(HttpServletRequest request) {
        int cabinetId = Integer.parseInt(request.getParameter("cabinetId"));
        return Result.OK("查询商品清单成功!",cabinetService.getGoodsByCabinetId(cabinetId));
    }

    @RequestMapping("/getCellsByGoodId")
    @ResponseBody
    public Result<String> getGoodByCabinetId(int goodId) {
        return Result.OK("查询商品位置成功!",cabinetService.getCellsByGoodId(goodId));
    }

    @RequestMapping(value = "/miniAppPay", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public Result<Map<String, String>> miniAppPay(HttpServletRequest request) {
        //需要通过授权来获取openId
        String openId = (String) request.getParameter("openId");
        String totalFee =(String) request.getParameter("totalFee");
        String ip = IpKit.getRealIp(request);

        WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();

        Map<String, String> params = UnifiedOrderModel
                .builder()
                .appid(wxPayApiConfig.getAppId())
                .mch_id(wxPayApiConfig.getMchId())
                .nonce_str(WxPayKit.generateStr())
                .body("八瑞科技-阿呜智慧支付")
                .attach("智慧寄存柜")
                .out_trade_no(WxPayKit.generateStr())
                .total_fee(totalFee)
                .spbill_create_ip(ip)
                .notify_url(notifyUrl)
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(openId)
                .build()
                .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);

        String xmlResult = WxPayApi.pushOrder(false, params);

        log.info(xmlResult);
        Map<String, String> result = WxPayKit.xmlToMap(xmlResult);

        String returnCode = result.get("return_code");
        String returnMsg = result.get("return_msg");
        if (!WxPayKit.codeIsOk(returnCode)) {
            return Result.Error(returnMsg);
        }
        String resultCode = result.get("result_code");
        if (!WxPayKit.codeIsOk(resultCode)) {
            return Result.Error(returnMsg);
        }
        // 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
        String prepayId = result.get("prepay_id");
        Map<String, String> packageParams = WxPayKit.miniAppPrepayIdCreateSign(wxPayApiConfig.getAppId(), prepayId,
                wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
        String jsonStr = JSON.toJSONString(packageParams);
        log.info("小程序支付的参数:" + jsonStr);
        return Result.OK("成功预下单",packageParams);
    }
}